﻿#region "Copyright (C) Lenny Granovsky. 2005-2013"
//This program is free software distribute under the terms of the GNU General Public License as published by
//the Free Software Foundation. Please read AssemblyInfo.cs file for more information.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Web.Enhancements.Rest.Templates
{
    /// <summary>
    /// This class provides essential functionality for creating and rendering HTML Templates.
    /// </summary>
    public class HtmlTemplateFactory
    {
        /// <summary>
        /// Method creates HTML template object with generic data source type.
        /// </summary>
        /// <typeparam name="TDataSource">Generic data source type.</typeparam>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="dataSource">Data source of generic type.</param>
        /// <returns>Returns HTML template object as IHtmlTemplate.</returns>
        public static IHtmlTemplate<TDataSource> CreateTemplate<TDataSource>(string virtualPath, TDataSource dataSource, Dictionary<string, object> tempData)
        {
            UserControl tmpCtrl = new System.Web.UI.UserControl();
            Control ctrl = tmpCtrl.LoadControl(virtualPath);
            IHtmlTemplate<TDataSource> myTmp = (IHtmlTemplate<TDataSource>)ctrl;
            myTmp.DataSource = dataSource;
            if (tempData != null)
                myTmp.TempData = tempData;
            ctrl.DataBind(); //should it be parameter?
            return myTmp;
        }

        /// <summary>
        /// Method creates HTML template object with generic data source type.
        /// </summary>
        /// <typeparam name="TDataSource">Generic data source type.</typeparam>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="dataSource">Data source of generic type.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        /// <returns>Returns HTML template object as IHtmlTemplate.</returns>
        public static IHtmlTemplate<TDataSource> CreateTemplate<TDataSource>(string virtualPath, TDataSource dataSource)
        {
            IHtmlTemplate<TDataSource> myTmp = CreateTemplate<TDataSource>(virtualPath, dataSource, null);
            return myTmp;
        }

        /// <summary>
        /// Method creates HTML template object.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="dataSource">Data source as type of object.</param>
        /// <returns>Returns HTML template object as HtmlTemplate.</returns>
        public static HtmlTemplate CreateTemplate(string virtualPath, object dataSource)
        {
            HtmlTemplate myTmp = (HtmlTemplate)CreateTemplate<object>(virtualPath, dataSource);
            return myTmp;
        }

        /// <summary>
        /// Method creates HTML template object.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="dataSource">Data source as type of object.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        /// <returns>Returns HTML template object as HtmlTemplate.</returns>
        public static HtmlTemplate CreateTemplate(string virtualPath, object dataSource, Dictionary<string, object> tempData)
        {
            HtmlTemplate myTmp = CreateTemplate(virtualPath, dataSource, tempData);
            return myTmp;
        }

        /// <summary>
        /// Method creates HTML template object that accepts no data.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <returns>Returns HTML template object as HtmlTemplate.</returns>
        public static HtmlTemplate CreateTemplate(string virtualPath)
        {
            HtmlTemplate myTmp = CreateTemplate(virtualPath, null);
            return myTmp;
        }

        /// <summary>
        /// Method creates HTML template object that accepts no data.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        /// <returns>Returns HTML template object as HtmlTemplate.</returns>
        public static HtmlTemplate CreateTemplate(string virtualPath, Dictionary<string, object> tempData)
        {
            HtmlTemplate myTmp = CreateTemplate(virtualPath, null, tempData);
            return myTmp;
        }

        /// <summary>
        /// Method creates HTML template object with generic data source type, 
        /// renders HTML template with given data source and writes result into an HtmlTextWriter.
        /// </summary>
        /// <typeparam name="TDataSource">Generic data source type.</typeparam>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="writer">HtmlTextWriter object to write rendered result to.</param>
        /// <param name="dataSource">Data source of generic type.</param>
        public static void RenderTemplate<TDataSource>(string virtualPath, HtmlTextWriter writer, TDataSource dataSource)
        {
            IHtmlTemplate<TDataSource> myTmp = CreateTemplate<TDataSource>(virtualPath, dataSource);
            myTmp.RenderTemplate(writer);
            ((Control)myTmp).Dispose();
        }

        /// <summary>
        /// Method creates HTML template object with generic data source type, 
        /// renders HTML template with given data source and writes result into an HtmlTextWriter.
        /// </summary>
        /// <typeparam name="TDataSource">Generic data source type.</typeparam>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="writer">HtmlTextWriter object to write rendered result to.</param>
        /// <param name="dataSource">Data source of generic type.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        public static void RenderTemplate<TDataSource>(string virtualPath, HtmlTextWriter writer, TDataSource dataSource, Dictionary<string, object> tempData)
        {
            IHtmlTemplate<TDataSource> myTmp = CreateTemplate<TDataSource>(virtualPath, dataSource, tempData);
            myTmp.RenderTemplate(writer);
            ((Control)myTmp).Dispose();
        }

        /// <summary>
        /// Method creates HTML template object that requires no data source, 
        /// renders HTML template and writes result into an HtmlTextWriter.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="writer">HtmlTextWriter object to write rendered result to.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        public static void RenderTemplate(string virtualPath, HtmlTextWriter writer, Dictionary<string, object> tempData)
        {
            RenderTemplate<object>(virtualPath, writer, null, tempData);
        }

        /// <summary>
        /// Method creates HTML template object that requires no data source, 
        /// renders HTML template and writes result into an HtmlTextWriter.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="writer">HtmlTextWriter object to write rendered result to.</param>
        public static void RenderTemplate(string virtualPath, HtmlTextWriter writer)
        {
            RenderTemplate<object>(virtualPath, writer, null, null);
        }

        /// <summary>
        /// Method creates HTML template object with generic data source type, 
        /// renders HTML template with given data source and returns result as a string of HTML.
        /// </summary>
        /// <typeparam name="TDataSource">Generic data source type.</typeparam>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="dataSource">Data source of generic type.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        /// <returns>HTML string that was rendered from the HTML Template.</returns>
        public static string RenderTemplate<TDataSource>(string virtualPath, TDataSource dataSource, Dictionary<string, object> tempData)
        {
            System.Text.StringBuilder sbr = new System.Text.StringBuilder();
            System.IO.StringWriter twr = new System.IO.StringWriter(sbr);
            Html32TextWriter writer = new Html32TextWriter(twr);
            RenderTemplate<TDataSource>(virtualPath, writer, dataSource, tempData);
            writer.Flush();
            return sbr.ToString();
        }

        /// <summary>
        /// Method creates HTML template object with generic data source type, 
        /// renders HTML template with given data source and returns result as a string of HTML.
        /// </summary>
        /// <typeparam name="TDataSource">Generic data source type.</typeparam>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="dataSource">Data source of generic type.</param>
        /// <returns>HTML string that was rendered from the HTML Template.</returns>
        public static string RenderTemplate<TDataSource>(string virtualPath, TDataSource dataSource)
        {
            return RenderTemplate<TDataSource>(virtualPath, dataSource, null);
        }

        /// <summary>
        /// Method creates HTML template object that requires no data source, 
        /// renders HTML template and returns result as a string of HTML.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <returns>HTML string that was rendered from the HTML Template.</returns>
        public static string RenderTemplate(string virtualPath)
        {
            return RenderTemplate<object>(virtualPath, null);
        }

        /// <summary>
        /// Method creates HTML template object that requires no data source, 
        /// renders HTML template and returns result as a string of HTML.
        /// </summary>
        /// <param name="virtualPath">Virtual path of HTML template (ascx) file location.</param>
        /// <param name="tempData">Extra data for HTML template.</param>
        /// <returns>HTML string that was rendered from the HTML Template.</returns>
        public static string RenderTemplate(string virtualPath, Dictionary<string, object> tempData)
        {
            object tmp = null;
            return RenderTemplate<object>(virtualPath, tmp, tempData);
        }
    }
}
